/*
 * @Author: yangni 920556271@qq.com
 * @Date: 2023-12-07 09:26:03
 * @LastEditors: yangni 920556271@qq.com
 * @LastEditTime: 2024-04-30 11:08:30
 * @FilePath: /yt-devops/lib/components/yt_form/widgets/reactive_map_pick.dart
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:reactive_forms/reactive_forms.dart';
import 'package:yt_devops/model/amap_poi.dart';
import 'package:yt_devops/routers/router_path.dart';
import 'package:yt_devops/utils/enums.dart';

typedef ReactiveMapPickerBuilder<T> = Widget Function(
    BuildContext context, ReactiveMapPickerDelegate<T> picker, Widget? child);

class ReactiveMapPicker<T> extends ReactiveFormField<T, AmapPoi> {
  ReactiveMapPicker({
    Key? key,
    String? formControlName,
    FormControl<T>? formControl,
    required ReactiveMapPickerBuilder<T> builder,
    Widget? child,
    dynamic Function(AmapPoi)? onConfirm,
    MapType mapType = MapType.amap,
  }) : super(
          key: key,
          formControl: formControl,
          formControlName: formControlName,
          builder: (ReactiveFormFieldState<T, AmapPoi> field) {
            return builder(
              field.context,
              ReactiveMapPickerDelegate<T>._(
                  field,
                  (field) => Get.toNamed(RouterPath.amapPage, arguments: {
                        'mapType': mapType.value,
                        'latitude': field.value?.latitude,
                        'longitude': field.value?.longitude
                      })?.then((value) {
                        if (value is AmapPoi) {
                          onConfirm?.call(value);
                          field.didChange(value);
                        }
                      })),
              child,
            );
          },
        );

  @override
  ReactiveFormFieldState<T, AmapPoi> createState() =>
      _ReactiveMapPickerState<T>();
}

/// Definition of the function responsible for show the date picker.
typedef _ShowMapPickerCallback<T> = void Function(
    ReactiveFormFieldState<T?, AmapPoi> field);

/// This class is responsible of showing the picker dialog.
///
/// See also [ReactiveMapPicker].
class ReactiveMapPickerDelegate<T> {
  final ReactiveFormFieldState<T, AmapPoi> _field;
  final _ShowMapPickerCallback<T> _showPickerCallback;

  ReactiveMapPickerDelegate._(this._field, this._showPickerCallback);

  /// Gets the control bound to the [ReactiveTimePicker] widget
  FormControl<T> get control => _field.control;

  /// Gets the value selected in the date picker.
  AmapPoi? get value => _field.value;

  /// Shows the time picker dialog.
  void showPicker() {
    _showPickerCallback(_field);
  }
}

class _ReactiveMapPickerState<T> extends ReactiveFormFieldState<T, AmapPoi> {
  @override
  ControlValueAccessor<T, AmapPoi> selectValueAccessor() {
    if (control is FormControl<AmapPoi>) {
      return super.selectValueAccessor();
    }

    throw ValueAccessorException('Invalid widget binding. ReactiveMapPicker '
        'widget must be bound to a control that inherited from '
        'AbstractControl<String> or AbstractControl<AmapPoi>. '
        'Control of type: ${control.runtimeType} is not valid.');
  }
}
